import random
import time

import pytest
import requests
import json
from unittest.mock import patch, MagicMock

# 配置信息
API_URL = "https://cvm.tencentcloudapi.com/"
REGION = "ap-guangzhou"
SECRET_ID = "your-secret-id"  # 实际测试中应从环境变量获取
SECRET_KEY = "your-secret-key"  # 实际测试中应从环境变量获取


def generate_signature(params, secret_key):
    """生成签名（模拟实现）"""
    # 实际签名算法需要按照腾讯云API规范实现
    # 这里仅作模拟
    return "mock-signature"


def send_request(action, params):
    """发送API请求（模拟实现）"""
    common_params = {
        "Action": action,
        "Version": "2017-03-12",
        "Region": REGION,
        "SecretId": SECRET_ID,
        "Timestamp": int(time.time()),
        "Nonce": random.randint(1, 1000000),
        "SignatureMethod": "HmacSHA256"
    }
    all_params = {**common_params, **params}
    all_params["Signature"] = generate_signature(all_params, SECRET_KEY)

    response = requests.post(API_URL, data=all_params)
    return response.json()


class TestModifyDiskMedia:
    @patch('requests.post')
    def test_modify_success(self, mock_post):
        """测试成功修改硬盘介质"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "DiskId": "disk-valid-id",
            "DiskType": "CLOUD_PREMIUM"
        }
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "RequestId" in result["Response"]

    @patch('requests.post')
    def test_modify_account_qualification(self, mock_post):
        """测试账户未通过资格审计"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "AccountQualificationRestrictions",
                    "Message": "该请求账户未通过资格审计"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "DiskId": "disk-valid-id",
            "DiskType": "CLOUD_PREMIUM"
        }
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "AccountQualificationRestrictions"

    @patch('requests.post')
    def test_modify_internal_error(self, mock_post):
        """测试内部错误"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InternalError.TradeUnknownError",
                    "Message": "内部错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "DiskId": "disk-valid-id",
            "DiskType": "CLOUD_PREMIUM"
        }
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "InternalError.TradeUnknownError"

    @patch('requests.post')
    def test_modify_unpaid_order(self, mock_post):
        """测试账户有未支付订单"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidAccount.UnpaidOrder",
                    "Message": "账户有未支付订单"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "DiskId": "disk-valid-id",
            "DiskType": "CLOUD_PREMIUM"
        }
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "InvalidAccount.UnpaidOrder"

    @patch('requests.post')
    def test_modify_unsupported_instance(self, mock_post):
        """测试不支持的实例"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidInstance.NotSupported",
                    "Message": "不被支持的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-unsupported",
            "DiskId": "disk-valid-id",
            "DiskType": "CLOUD_PREMIUM"
        }
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "InvalidInstance.NotSupported"

    @patch('requests.post')
    def test_modify_malformed_instance_id(self, mock_post):
        """测试无效格式的实例ID"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidInstanceId.Malformed",
                    "Message": "无效实例ID。指定的实例ID格式错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "invalid-ins-id",
            "DiskId": "disk-valid-id",
            "DiskType": "CLOUD_PREMIUM"
        }
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "InvalidInstanceId.Malformed"

    @patch('requests.post')
    def test_modify_not_found_instance(self, mock_post):
        """测试实例不存在"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidInstanceId.NotFound",
                    "Message": "没有找到相应实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-not-found",
            "DiskId": "disk-valid-id",
            "DiskType": "CLOUD_PREMIUM"
        }
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "InvalidInstanceId.NotFound"

    @patch('requests.post')
    def test_modify_invalid_parameter(self, mock_post):
        """测试参数错误"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameter",
                    "Message": "参数错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "DiskId": "disk-valid-id",
            "DiskType": "CLOUD_PREMIUM",
            "InvalidParam": "invalid-value"  # 额外的无效参数
        }
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "InvalidParameter"

    @patch('requests.post')
    def test_modify_cloud_disk_sold_out(self, mock_post):
        """测试云盘资源售罄"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameter.InvalidCloudDiskSoldOut",
                    "Message": "云盘资源售罄"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "DiskId": "disk-valid-id",
            "DiskType": "CLOUD_PREMIUM"
        }
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "InvalidParameter.InvalidCloudDiskSoldOut"

    @patch('requests.post')
    def test_modify_instance_type_not_supported(self, mock_post):
        """测试不支持的实例类型"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameter.InvalidInstanceNotSupported",
                    "Message": "当前操作不支持该类型实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-unsupported-type",
            "DiskId": "disk-valid-id",
            "DiskType": "CLOUD_PREMIUM"
        }
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "InvalidParameter.InvalidInstanceNotSupported"

    @patch('requests.post')
    def test_modify_invalid_parameter_value(self, mock_post):
        """测试参数取值错误"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameterValue",
                    "Message": "参数取值错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "DiskId": "disk-valid-id",
            "DiskType": "INVALID_TYPE"  # 无效的磁盘类型
        }
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "InvalidParameterValue"

    @patch('requests.post')
    def test_modify_malformed_instance_id_format(self, mock_post):
        """测试实例ID格式不符合要求"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameterValue.InstanceIdMalformed",
                    "Message": "实例ID不合要求，请提供规范的实例ID"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "INS-VALID-ID",  # 大写字母不合法
            "DiskId": "disk-valid-id",
            "DiskType": "CLOUD_PREMIUM"
        }
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "InvalidParameterValue.InstanceIdMalformed"

    @patch('requests.post')
    def test_modify_local_disk_size_range(self, mock_post):
        """测试本地盘大小超出限制"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameterValue.LocalDiskSizeRange",
                    "Message": "本地盘的限制范围"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "DiskId": "disk-local",  # 本地盘
            "DiskType": "CLOUD_PREMIUM",
            "DiskSize": 1000  # 假设超出限制的大小
        }
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "InvalidParameterValue.LocalDiskSizeRange"

    @patch('requests.post')
    def test_modify_invalid_permission(self, mock_post):
        """测试账户不支持该操作"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidPermission",
                    "Message": "账户不支持该操作"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "DiskId": "disk-valid-id",
            "DiskType": "CLOUD_PREMIUM"
        }
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "InvalidPermission"

    @patch('requests.post')
    def test_modify_missing_parameter(self, mock_post):
        """测试缺少必要参数"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "MissingParameter",
                    "Message": "缺少参数错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {}  # 空参数
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "MissingParameter"

    @patch('requests.post')
    def test_modify_task_running(self, mock_post):
        """测试相同任务正在运行"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "MutexOperation.TaskRunning",
                    "Message": "同样的任务正在运行"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "DiskId": "disk-valid-id",
            "DiskType": "CLOUD_PREMIUM"
        }
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "MutexOperation.TaskRunning"

    @patch('requests.post')
    def test_modify_instance_in_progress(self, mock_post):
        """测试实例正在执行其他操作"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "OperationDenied.InstanceOperationInProgress",
                    "Message": "实例正在执行其他操作，请稍后再试"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-in-progress",
            "DiskId": "disk-valid-id",
            "DiskType": "CLOUD_PREMIUM"
        }
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "OperationDenied.InstanceOperationInProgress"

    @patch('requests.post')
    def test_modify_cloud_disk_sold_out_resource(self, mock_post):
        """测试指定的云盘规格已售罄"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "ResourceInsufficient.CloudDiskSoldOut",
                    "Message": "指定的云盘规格已售罄"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "DiskId": "disk-valid-id",
            "DiskType": "CLOUD_PREMIUM"
        }
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "ResourceInsufficient.CloudDiskSoldOut"

    @patch('requests.post')
    def test_modify_edge_zone_not_support(self, mock_post):
        """测试边缘可用区不支持云盘操作"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.EdgeZoneNotSupportCloudDisk",
                    "Message": "所选择的边缘可用区不支持云盘操作"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "DiskId": "disk-valid-id",
            "DiskType": "CLOUD_PREMIUM",
            "Zone": "edge-zone"  # 边缘可用区
        }
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.EdgeZoneNotSupportCloudDisk"

    @patch('requests.post')
    def test_modify_instance_running(self, mock_post):
        """测试不支持开机状态的实例"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceStateRunning",
                    "Message": "请求不支持开机状态的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-running",
            "DiskId": "disk-valid-id",
            "DiskType": "CLOUD_PREMIUM"
        }
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceStateRunning"

    @patch('requests.post')
    def test_modify_instance_shutdown(self, mock_post):
        """测试不支持隔离状态的实例"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceStateShutdown",
                    "Message": "请求不支持隔离状态的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-shutdown",
            "DiskId": "disk-valid-id",
            "DiskType": "CLOUD_PREMIUM"
        }
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceStateShutdown"

    @patch('requests.post')
    def test_modify_instance_starting(self, mock_post):
        """测试实例开机中不允许操作"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceStateStarting",
                    "Message": "实例开机中，不允许该操作"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-starting",
            "DiskId": "disk-valid-id",
            "DiskType": "CLOUD_PREMIUM"
        }
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceStateStarting"

    @patch('requests.post')
    def test_modify_instance_stopping(self, mock_post):
        """测试不支持正在关机的实例"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceStateStopping",
                    "Message": "请求不支持正在关机的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-stopping",
            "DiskId": "disk-valid-id",
            "DiskType": "CLOUD_PREMIUM"
        }
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceStateStopping"

    @patch('requests.post')
    def test_modify_stop_charging_not_supported(self, mock_post):
        """测试不支持关机不收费特性"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.StoppedModeStopCharging",
                    "Message": "不支持关机不收费特性"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-stop-charging",
            "DiskId": "disk-valid-id",
            "DiskType": "CLOUD_PREMIUM"
        }
        result = send_request("ModifyInstanceDiskType", params)

        assert "Response" in result
        assert "Error" in result["Response"]
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.StoppedModeStopCharging"


# 启动测试函数
def run_tests():
    pytest.main([__file__, "-v", "-s"])


if __name__ == "__main__":
    run_tests()